﻿#include "CommandManager.h"
#include <QDebug>
#include "CommandManager/CommandBase.h"
#include "BaseModule/IBaseSignal.h"

namespace CommandManager
{
    CommandManager* CommandManager::m_instance = nullptr;

    CommandManager* CommandManager::getInstance()
    {
        if (m_instance == nullptr)
        {
            m_instance = new CommandManager;
        }
        return m_instance;
    }

    CommandManager::CommandManager()
    {
        auto _baseSignal = IBaseSignalInstance;
        connect(_baseSignal, &BaseModule::IBaseSignal::signal_execCommand, this, &CommandManager::slot_execCommand, Qt::DirectConnection);
        connect(_baseSignal, &BaseModule::IBaseSignal::signal_execCommandManager, this, &CommandManager::slot_execCommandManager);
    }

    void CommandManager::undo()
    {
        if (m_undoMap.size() < 1)  return;

        auto _command = m_undoMap.last();
        _command->undo();

        m_undoMap.removeLast();
        m_redoMap.append(_command);
    }

    void CommandManager::redo()
    {
        if (m_redoMap.size() < 1)  return;

        auto _command = m_redoMap.last();
        _command->redo();

        m_redoMap.removeLast();
        m_undoMap.append(_command);
    }

    /// @brief 执行命令管理

    void CommandManager::slot_execCommandManager(BaseModule::ECommandManager commandType)
    {
        switch (commandType)
        {
        case BaseModule::ECommandManager::Undo:
            this->undo(); break;
        case BaseModule::ECommandManager::Redo:
            this->redo(); break;
        case BaseModule::ECommandManager::ClearAllCommand:
            this->clearAllCommands(); break;
        default:
            break;
        }
    }

    /// @brief 执行命令

    void CommandManager::slot_execCommand(CommandBase* command, bool* state)
    {
        if (!command)
        {
            QString _errorText = QObject::tr("Failed to execute the command, command is null.");
            emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Error, _errorText);
            return;
        }
        if (!state)
        {
            QString _errorText = QObject::tr("Failed to execute the '%1', state is null.").arg(command->getCmdName());
            emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Error, _errorText);
            return;
        }
        
        bool _isSuccessed = command->execute();

        if (_isSuccessed)
        {
            m_undoMap.append(command);
            CommandManagerInstance->clearRedoCommands();
        }
        else
        {
            qDebug() << QString("Failed to execute the '%1' command.").arg(command->getCmdName());
            delete command;
            command = nullptr;
        }

        *state = _isSuccessed;
    }


    /// @brief 获取undo列表大小

    int CommandManager::getUndoListSize() 
    { 
        return m_undoMap.size();
    }

    /// @brief 获取redo列表大小

    int CommandManager::getRedoListSize() 
    { 
        return m_redoMap.size();
    }


    void CommandManager::clearRedoCommands()
    {
        qDeleteAll(m_redoMap);
        m_redoMap.clear();
    }

    void CommandManager::clearAllCommands()
    {
        clearRedoCommands();

        qDeleteAll(m_undoMap);
        m_undoMap.clear();
    }


}

